package com.aries.remoteplusserver.core;

import java.awt.AWTException;
import java.awt.GraphicsDevice;
import java.awt.GraphicsEnvironment;
import java.awt.MouseInfo;
import java.awt.Point;
import java.awt.PointerInfo;
import java.awt.Rectangle;
import java.awt.Robot;
import java.awt.event.InputEvent;
import java.awt.event.KeyEvent;

import com.jinvoke.JInvoke;
import com.jinvoke.win32.User32;
import static com.jinvoke.win32.WinConstants.*;

public class BasicInputHandler {

	private Robot robot;
	private static final float sensitivity = 1.6f;
	private float xLeftover = 0; 
	private float yLeftover = 0; 
	private Rectangle[] gBounds; 
	private GraphicsDevice[] graphicsDevices;
	
	public BasicInputHandler() throws AWTException
	{
		JInvoke.initialize();
		this.robot = new Robot();
		this.robot.setAutoDelay(5);
		
		this.graphicsDevices = GraphicsEnvironment.getLocalGraphicsEnvironment().getScreenDevices();
		this.gBounds = new Rectangle[this.graphicsDevices.length];
		
		for (int i = 0; i < this.graphicsDevices.length; i++)
		{
			this.gBounds[i] = this.graphicsDevices[i].getDefaultConfiguration().getBounds();
		}
	}
	
	public void mouseMoveHandler(Object[] args)
	{
		float xOffset = Float.parseFloat(args[1].toString());
		float yOffset = Float.parseFloat(args[2].toString());
		
		PointerInfo pointerInfo = MouseInfo.getPointerInfo();
		
		if (pointerInfo != null) 
		{
			Point point = pointerInfo.getLocation();
			
			//Date nDate = new Date(System.currentTimeMillis());
			//System.out.println(point.toString() + nDate.toString());
			
			float ox = (xOffset * sensitivity) + xLeftover;
			float oy = (yOffset * sensitivity) + yLeftover;				
			int ix = Math.round(ox);
			int iy = Math.round(oy);
			xLeftover = ox-ix;
			yLeftover = oy-iy;
			
			point.x += ix;
			point.y += iy;
			int l = gBounds.length;
			
			for (int i = 0; i < l; ++i) 
			{
				if ( this.gBounds[i].contains(point) ) 
				{
					this.robot.mouseMove(point.x, point.y);
					break;
				}
			}
			
			try
			{
				this.robot.mouseMove(point.x, point.y);
			} catch (Exception e){}
		}
	}

	public void buttonHandler(Object[] args, int buttonMask)
	{
		boolean isDrag = Boolean.parseBoolean(args[0].toString());
		
		if (isDrag && buttonMask==InputEvent.BUTTON1_MASK)
		{
			this.robot.mousePress(buttonMask);
		}
		else 
		{
			this.robot.mousePress(buttonMask);
			this.robot.mouseRelease(buttonMask);	
		}
	}
	
	public void wheelScrollHandler(Object[] args)
	{
		int dir = Integer.parseInt(args[1].toString());
		this.robot.mouseWheel(dir);
	}
	
	public void textInputHandler(Object[] args)
	{
		String inputText = args[0].toString();
		/*JInvoke Call*/
		com.jinvoke.win32.structs.Point cursorPoint = new com.jinvoke.win32.structs.Point();
		User32.GetCursorPos(cursorPoint);
		int hWnd = User32.WindowFromPoint(cursorPoint.x, cursorPoint.y);
		
		for (int i = 0; i < inputText.length(); i++)
		{
			User32.PostMessage(hWnd, WM_CHAR, inputText.charAt(i), 0);
		}
		//JNIWindowUtilProxy.setWindowText(inputText);
	}
	
	public void softKeyHandler(Object[] args)
	{
		String softKeyType = args[0].toString();
		
		if ( softKeyType.equals("DELETE") )
		{
			this.robot.keyPress(KeyEvent.VK_BACK_SPACE);
			this.robot.keyRelease(KeyEvent.VK_BACK_SPACE);	
		}
		else if ( softKeyType.equals("ENTER") )
		{
			this.robot.keyPress(KeyEvent.VK_ENTER);
			this.robot.keyRelease(KeyEvent.VK_ENTER);
		}
	}
}
